<template>
  <div class="right-tools" :class="{ showLeft: drawer }">
    <div
      v-for="(tool, idx) in tools"
      :key="idx"
      :class="tool.id == groupInfo.id ? 'tool-item active' : 'tool-item'"
      @click="handleClick(tool)"
    >
      <img
        :src="require('@/assets/images/' + tool.icon + '.png')"
        class="toolImg"
      />
      <span>{{ tool.label }}</span>
    </div>
    <div class="progressStyle" v-if="aiSilent">
      <div class="line"></div>

      <el-progress
        type="circle"
        :width="42"
        :percentage="calculatePercentage"
        :format="format"
        color="#165DEB"
        text-color="#165DEB"
        define-back-color="#d3dff8"
      ></el-progress>

      <el-popover
        placement="left"
        width="270"
        trigger="manual"
        v-model="aiVisible"
      >
        <p>AI静默生成内容已完成，可前往故事框架中查看</p>
        <div style="text-align: right; margin: 0">
          <el-button size="mini" type="text" @click="aiCreateCancelJm(false)"
            >忽略</el-button
          >
          <!-- <el-button type="primary" size="mini" @click="aiCreateCancelJm(true)"
            >查看</el-button
          > -->
        </div>
        <div class="text" slot="reference">AI工具生成中</div>
      </el-popover>
    </div>
    <div class="box" v-if="drawer">
      <div class="close">
        <i class="el-icon-close" @click="handleClick({ id: groupInfo.id })"></i>
      </div>
      <div class="top">
        <div class="name">{{ groupInfo.name }}</div>
        <div class="desc">构建一个完整而有深度的世界观</div>
        <div class="qlbj">
          <el-tooltip
            effect="light"
            :open-delay="1000"
            placement="left"
            popper-class="tooltip"
            :visible-arrow="false"
          >
            <div slot="content">
              全量编排：一次性可多选该工具内的所有AI工具<br />单项编排：只能多选该子分类的AI工具
            </div>
            <i class="el-icon-question"></i>
          </el-tooltip>
          <el-button
            type="text"
            @click="toggleFullSelect"
            :disabled="selectGroup != -1"
            >{{ isFullSelect ? "全选" : "全量编排" }}</el-button
          >
        </div>
      </div>
      <template v-if="groupInfo.groups.length">
        <div class="center">
          <div class="item" v-for="(item, i) in groupInfo.groups" :key="i">
            <div class="item-top">
              <div class="name">{{ item.name }}</div>
              <div class="desc">{{ item.desc }}</div>
              <el-button
                class="dxbj"
                type="text"
                :class="{ disabled: isSingleSelect }"
                @click="toggleSingleSelect(item)"
                :disabled="selectGroup != -1 && selectGroup != item.id"
              >
                {{ item.hasSelect ? "单选全选" : "单项编排" }}
              </el-button>
            </div>

            <div class="list">
              <el-tooltip
                effect="light"
                :open-delay="1000"
                :visible-arrow="false"
                popper-class="tooltip"
                :content="item2.desc ? item2.desc : '暂无描述信息'"
                placement="bottom"
                v-for="(item2, i2) in item.prompts"
                :key="i2"
              >
                <div
                  class="xx"
                  :class="{ active: item2.selected }"
                  @click="selectItem(item2, item.hasSelect)"
                >
                  {{ item2.title }}
                </div>
              </el-tooltip>
            </div>
          </div>
        </div>
        <div class="bottom" v-if="isFullSelect || selectGroup != -1">
          <div class="left">已选: {{ selectedCount }}</div>
          <div class="right">
            <el-button @click="qxSelect">取消</el-button>
            <el-button type="primary" @click="goBp()">确定</el-button>
          </div>
        </div>
      </template>
      <div v-else class="noDate">
        <img src="@/assets/images/zzzw.png" alt="" />
        暂无数据
      </div>
    </div>
    <el-dialog
      :visible.sync="aiDialogVisible"
      width="600px"
      custom-class="aiDialog"
      :show-close="false"
      center
    >
      <span slot="title"></span>
      <div class="top">AI一键生成中</div>
      <div class="progress">
        <el-progress
          :text-inside="true"
          :stroke-width="20"
          :format="format"
          text-color="#fff"
          :percentage="calculatePercentage"
        ></el-progress>
      </div>
      <div class="aiDesc">
        预计还需要等待2分钟，可以选择等待或后台静默运行，完成后将通知您
        生成的内容会保存到故事框架中
      </div>
      <div class="dialog-footer">
        <el-button @click="aiCreateQx">取 消</el-button>
        <el-button type="primary" @click="aiCreateJm">后台静默运行</el-button>
      </div>
    </el-dialog>
    <el-dialog :title="modelTitle" :visible.sync="modelShow" width="540" center>
      <el-form
        label-position="top"
        :model="form"
        :rules="rules"
        ref="formRef"
        class="tkBox"
        label-width="80px"
      >
        <el-form-item label="选择模型" prop="selectedVendor">
          <el-dropdown
            class="dropdown-wrapper"
            trigger="click"
            placement="bottom-start"
            popper-class="xlClass"
          >
            <span class="el-dropdown-link">
              {{ form.selectedVendor || "请选择" }}
              <i class="el-icon-arrow-down el-dropdown-link-icon"></i>
            </span>

            <el-dropdown-menu slot="dropdown" class="dropdown-wrapper-list">
              <div class="moTitle">选择厂商</div>
              <el-popover
                v-for="(models, provider) in modelList"
                placement="right"
                :value="showMx && showMxType == provider"
              >
                <div class="moTitle">选择模型</div>
                <el-radio-group
                  v-model="form.selectedVendor"
                  @input="showMx = false"
                  class="myradio"
                >
                  <el-radio
                    v-for="item in modelList[provider]"
                    :label="item.model_name"
                    >{{ item.model_name }}</el-radio
                  >
                </el-radio-group>
                <el-dropdown-item slot="reference" :key="provider">
                  <div
                    :class="provider == showMxType ? 'active' : ''"
                    style="
                      display: flex;
                      justify-content: space-between;
                      align-items: center;
                    "
                    @mouseover="handleMouseOver(provider)"
                  >
                    {{ provider }} <i class="el-icon-arrow-right"></i>
                  </div>
                </el-dropdown-item>
              </el-popover>
            </el-dropdown-menu>
          </el-dropdown>
          <div class="moText">{{ getModelDesc(form.selectedVendor) }}</div>
        </el-form-item>
        <el-form-item label="关联上下文" prop="type">
          <el-select
            v-model="form.type"
            placeholder="请选择关联类型"
            style="width: 100%"
          >
            <el-option label="默认关联" :value="1"></el-option>
            <el-option label="不关联" :value="3"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div class="dialog-footer">
        <el-button @click="modelShow = false">取消</el-button>
        <el-button type="primary" @click="toolSave">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  cancelAi,
  creteArrange,
  getStages,
  getStat,
  getStatus,
  getTools,
  setAiJm,
  setCancelAiJm,
} from "@/api/tk";
import { chapterUpdate } from "@/api/chapter";
import { conversationCreate } from "@/api/conversation";
import { getCreationsList } from "@/api/work";
import Vue from "vue";
import {
  conversationLoop,
  conversationModels,
  conversationDefault,
} from "@/api/conversations";

export default {
  name: "RightTools",
  data() {
    return {
      showMx: false,
      showMxType: "",
      createAiId: "",
      aiSilent: false,
      aiVisible: false,
      aiStatus: "",
      aiAll: 0,
      aiCompleted: 0,
      aiDialogVisible: false,
      selectGroup: -1,
      loading: false,
      creation_id: "",
      modelTitle: "世界观",
      modelValue: "",
      centerDialogVisible: false,
      modelShow: false,
      drawer: false,
      menus: [],
      modelList: [],
      groupInfo: {
        groups: [],
      },
      form: { selectedVendor: "", type: 1, desc: "" },
      rules: {
        selectedVendor: [
          { required: true, message: "请选择模型", trigger: "change" },
        ],
        type: [{ required: true, message: "请选择题材", trigger: "change" }],
      },
      tools: [
        { label: "世界观", icon: "sjk", id: 2 },
        { label: "构思大纲", icon: "gsdg", id: 3 },
        { label: "分卷规划", icon: "fjgh", id: 4 },
        { label: "制定章纲", icon: "zdgl", id: 5 },
        { label: "正文写作", icon: "zwxz", id: 6 },
        { label: "润色打磨", icon: "rsdm", id: 7 },
        { label: "通用工具", icon: "tygj", id: 8 },
      ],
      selectedItems: [], // 选中的子项
      isFullSelect: false, // 全量编排的选择状态
      isSingleSelect: false, // 单选编排的选择状态
    };
  },
  mounted() {
    this.creation_id = Number(this.$route.params.id);
    this.getstatFun();
    this.getAiMx();
    this.getDefaultModel();
  },
  computed: {
    calculatePercentage() {
      return parseInt((this.aiCompleted / this.aiAll) * 100);
    },
    selectedCount() {
      return this.selectedItems.length;
    },
  },
  methods: {
    //给外部调用的，创建状态ai一键生成
    handleCreateStatus(id) {
      this.createAiId = id;
      this.aiDialogVisible = true;
      this.aiSilent = true;
      this.getAiStatus();
    },

    //获取默认模型
    async getDefaultModel() {
      const response = await conversationDefault();
      this.form.selectedVendor = response.model_name;
    },
    //获取模型描述
    getModelDesc(model_name) {
      const list = Object.values(this.modelList).flat();
      const item = list.find((x) => x.model_name == model_name);
      return item ? item.billing : "";
    },

    handleMouseOver(item) {
      this.showMx = true;
      this.showMxType = item;
    },
    getAiMx() {
      conversationModels({}).then((res) => {
        console.log(res);
      });
    },
    format() {
      return `${this.aiCompleted} / ${this.aiAll}`; // 自定义显示格式
    },
    /** 转换菜单数据结构 */
    normalizer(node) {
      if (node.children && !node.children.length) {
        delete node.children;
      }
      return {
        id: node.menuId,
        label: node.menuName,
        children: node.children,
      };
    },
    async goBp() {
      if (this.selectedCount > 0) {
        let data = await conversationModels({});
        this.modelList = data;
        this.modelShow = true;
      } else {
        this.$message.error("请先选择");
      }
    },
    toolBp() {},
    async goTool(item) {
      this.modelTitle = item.title;
      this.modelValue = item.name;
      let data = await conversationModels({});
      this.modelList = data;
      this.modelShow = true;
    },
    async toolSave() {
      if (this.isFullSelect || this.selectGroup != -1) {
        //   编排
        this.loading = true;
        var groups = [];
        this.groupInfo.groups.forEach((group) => {
          if (group.hasSelect) {
            var obj = {};
            obj.group_id = group.id;
            obj.element_ids = [];
            group.prompts.forEach((item) => {
              if (item.selected) {
                obj.element_ids.push(item.name);
              }
            });

            groups.push(obj);
          }
        });

        try {
          if (this.form.selectedVendor == "") {
            this.$message.error("请选择模型");
            return false;
          }
          const params = {
            pattern: this.form.type,
            creation_id: this.creation_id,
            elements: {
              stage_id: this.groupInfo.id,
              groups: groups,
            },
            model: this.form.selectedVendor, // 示例输入
          };
          console.log(params);
          const response = await creteArrange(params);

          this.createAiId = response.id;
          this.modelShow = false;
          this.getAiStatus();
          this.aiDialogVisible = true;
        } catch (error) {
          this.$message.error(error);
        }
      } else {
        //工具
        this.loading = true;
        try {
          const response = await conversationCreate({
            pattern: this.form.type,
            model: this.form.selectedVendor,
            ai_tool_id: this.modelValue,
            creation_id: this.creation_id,
            user_input: this.form.desc, // 示例输入
          });
          this.modelShow = false;
          this.handleClick({ id: this.groupInfo.id });
          this.$emit("changeDldh", {
            type: "openNew",
            id: response.conversation_id,
            show_prompt: response.show_prompt,
          });
        } catch (error) {
          this.$message.error("创建新对话失败");
        }
      }
    },
    getstatFun() {
      getStat({
        creation_id: this.creation_id, // unsigned integer, required
      }).then((res) => {
        if (res.length > 0) {
          res.forEach((d) => {
            if (d.task_type == 1) {
              //编排任务
              this.aiSilent = d.silent;
              if (d.silent) {
                this.aiDialogVisible = false;
              } else {
                this.aiDialogVisible = true;
              }
              this.createAiId = d.id;
              this.aiStatus = d.status;
              this.aiAll = d.totals;
              this.aiCompleted = d.completed;
              if (d.status == 2) {
                this.getAiStatus();
              }
            }
          });
        }
      });
    },
    aiCreateQx() {
      cancelAi({ task_id: this.createAiId }).then((res) => {
        console.log(res);
      });
    },
    aiCreateJm() {
      setAiJm({ task_id: this.createAiId }).then((res) => {
        console.log(res);
        this.aiDialogVisible = false;
        this.aiSilent = true;
      });
    },
    aiCreateCancelJm(type) {
      this.aiVisible = false;
      setCancelAiJm({ task_id: this.createAiId }).then((res) => {
        this.aiSilent = false;
      });
      if (type) {
        this.$message.success("取消静默,并执行查看逻辑");
      } else {
        this.$message.success("取消静默");
      }
    },
    async getAiStatus() {
      var that = this;
      try {
        const response = await getStatus({
          task_id: this.createAiId,
        });
        this.aiStatus = response.status;
        this.aiAll = response.totals;
        this.aiCompleted = response.completed;

        if (response.status == 4) {
          this.$message.error("编排创建失败请重试");
          this.aiDialogVisible = false;
        }
        // 1=未开始, 2=进行中, 3=已取消, 4=已出错, 5=已完成
        if (response.status == 2) {
          setTimeout(function () {
            that.getAiStatus();
          }, 5000);
        }
        if (response.status == 5) {
          this.$message.success("已完成");
          //未开启静默
          if (this.aiDialogVisible) {
            this.$message.success("已编排成功");
            this.aiDialogVisible = false;
            this.$emit("openWrite");
          } else {
            //开启静默了
            if (this.aiSilent) {
              this.aiVisible = true;
            }
          }
        }
        if (response.status == 3) {
          this.$message.error("已取消");
          this.aiDialogVisible = false;
        }
      } catch (error) {
        this.$message.error("创建新对话失败");
      }
    },
    handleClose() {
      this.drawer = false;
      this.$emit("changeDldh", { type: "show" });
    },
    qxSelect() {
      this.groupInfo.groups.forEach((group) => {
        group.hasSelect = false;
        group.prompts.forEach((item) => {
          item.selected = false;
        });
      });
      this.isFullSelect = false;
      this.selectGroup = -1;
    },
    handleClick(tool) {
      if (tool.id == this.groupInfo.id) {
        this.drawer = false;
        this.groupInfo = {
          groups: [],
        };
        return false;
      }
      this.drawer = true;
      this.$emit("changeDldh", { type: "close" });
      getTools({ stage_seq: tool.id }).then((res) => {
        res.groups.forEach((group) => {
          group.hasSelect = false;
          group.prompts.forEach((item) => {
            item.selected = false;
          });
        });
        this.groupInfo = res;
      });
    },
    toggleFullSelect() {
      if (this.isFullSelect) {
        let flag = this.groupInfo.groups[0].prompts[0].selected;
        this.groupInfo.groups.forEach((group) => {
          group.hasSelect = true;
          group.prompts.forEach((item) => {
            item.selected = !flag;
          });
        });
        this.selectedItems = this.groupInfo.groups.flatMap((group) =>
          group.prompts.filter((i) => i.selected)
        );
      } else {
        this.selectGroup = -1;
        this.isFullSelect = true;
        this.groupInfo.groups.forEach((group) => {
          group.hasSelect = true;
        });
      }
    },
    toggleSingleSelect(item) {
      if (item.hasSelect) {
        let flag = item.prompts[0].selected;
        item.prompts.forEach((item) => {
          item.selected = !flag;
        });
        this.selectedItems = this.groupInfo.groups.flatMap((group) =>
          group.prompts.filter((i) => i.selected)
        );
      } else {
        item.hasSelect = true;
        this.selectGroup = item.id;
      }
    },
    selectItem(item, type) {
      if (type) {
        item.selected = !item.selected;
        this.selectedItems = this.groupInfo.groups.flatMap((group) =>
          group.prompts.filter((i) => i.selected)
        );
      } else {
        if (this.selectGroup == -1) {
          this.goTool(item);
        }
      }
    },
  },
};
</script>
<style>
.progressStyle {
  text-align: center;

  .line {
    width: 40px;
    height: 1px;
    background: rgba(0, 0, 0, 0.08);
    border-radius: 0px 0px 0px 0px;
    margin: 0 auto;
    margin-bottom: 48px;
  }

  .text {
    font-size: 12px;
    color: #00011b;
    line-height: 14px;
    text-align: center;
    margin-top: 10px;
    padding: 0 10px;
  }
}

.tooltip {
  font-size: 12px !important;
  color: rgba(0, 1, 27, 0.5) !important;
  line-height: 14px !important;
  border: 1px solid #f0f0f0 !important;
}

.aiDialog {
  .el-dialog__header {
    display: none;
  }

  .dialog-footer {
    box-shadow: none;
  }

  .el-dialog__body {
    padding: 0;
    padding-bottom: 80px !important;
  }

  .top {
    background-image: url("../../../assets/images/aiTop.png");
    width: 100%;
    height: 110px;
    background-size: cover;
    line-height: 110px;
    text-align: center;
    font-size: 20px;
    color: #00011b;
    font-weight: bold;
  }

  .progress {
    padding: 0 48px;
  }

  .aiDesc {
    margin-top: 40px;
    padding: 0 100px;
    font-size: 13px;
    color: rgba(0, 1, 27, 0.5);
    line-height: 21px;
    text-align: center;
  }
}
</style>
<style scoped lang="scss">
.noDate {
  text-align: center;
  padding: 180px 0;
  font-size: 14px;
  color: rgba(0, 1, 27, 0.3);

  img {
    width: 140px;
    display: block;
    margin: 0 auto;
  }
}
.el-dropdown-menu {
  width: 495px;
}

.active {
  background: rgba(242, 244, 248, 1);
}

.myradio {
  display: flex;
  flex-direction: column;

  .el-radio {
    line-height: 32px;
    margin-bottom: 10px;
  }
}

.box {
  z-index: 1111;
  position: absolute;
  height: 100%;
  width: 440px;
  top: 0;
  right: 68px;
  background: #ffffff;
  border-radius: 12px 0px 0px 0px;
  box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.08);

  .top {
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 0 16px;
    height: 84px;
    position: relative;
    z-index: 1;
    background: #fff;

    .name {
      font-size: 16px;
      color: #00011b;
      line-height: 20px;
      font-weight: bold;
    }

    .desc {
      font-size: 13px;
      color: rgba(0, 1, 27, 0.5);
      line-height: 15px;
      margin-top: 5px;
    }

    .qlbj {
      position: absolute;
      top: 20px;
      right: 16px;
      font-weight: 400;
      font-size: 14px;
      color: #165deb;
      line-height: 20px;
      text-align: right;
      font-style: normal;
      text-transform: none;
      cursor: pointer;

      i {
        color: rgba(0, 1, 27, 0.3);
        margin-right: 5px;
      }
    }
  }

  .center {
    position: absolute;
    height: 100%;
    padding-top: 84px;
    padding-bottom: 64px;
    overflow-y: auto;
    width: 100%;
    left: 0;
    top: 0;

    .item {
      margin-top: 25px;

      .item-top {
        height: 43px;
        border-radius: 0px 0px 0px 0px;
        display: flex;
        flex-direction: column;
        justify-content: center;
        border-left: 2px solid #165deb;
        padding: 0 16px;
        position: relative;

        .dxbj {
          position: absolute;
          top: 0px;
          right: 16px;
          font-weight: 400;
          font-size: 14px;
          line-height: 20px;
          text-align: right;
          font-style: normal;
          text-transform: none;
          cursor: pointer;

          i {
            color: rgba(0, 1, 27, 0.3);
            margin-right: 5px;
          }
        }

        .name {
          font-size: 14px;
          color: #00011b;
          line-height: 16px;
          font-weight: bold;
        }

        .desc {
          font-size: 12px;
          color: rgba(0, 1, 27, 0.5);
          line-height: 14px;
          margin-top: 5px;
        }
      }

      .list {
        overflow: hidden;
        display: flex;
        justify-content: start;
        flex-wrap: wrap;

        .xx {
          cursor: pointer;
          width: 125px;
          height: 37px;
          background: #f2f4f8;
          border-radius: 4px 4px 4px 4px;
          border: 1px solid rgba(0, 0, 0, 0.08);
          padding: 8px 4px;
          margin-top: 16px;
          margin-left: 16px;
          font-size: 12px;
          color: #00011b;
          text-align: center;
          line-height: 19px;
          white-space: nowrap;
          /* 不换行 */
          overflow: hidden;
          /* 隐藏超出的内容 */
          text-overflow: ellipsis;
          /* 用省略号表示被隐藏的部分 */
        }

        .xx.active {
          background: #f6f9ff;
          border-radius: 4px 4px 4px 4px;
          border: 1px solid #165deb;
          color: #165deb;
        }
      }
    }
  }

  .bottom {
    align-items: center;
    padding: 0 16px;
    position: absolute;
    bottom: 0;
    height: 64px;
    background: #ffffff;
    box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.08);
    border-radius: 0px 0px 0px 0px;
    width: 100%;
    display: flex;
    justify-content: space-between;
  }
}

.right-tools {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  height: 100%;
  padding-top: 26px;
  background-color: #fff;
  position: relative;
  &.showLeft {
    z-index: 2;
  }
  .tool-item {
    cursor: pointer;
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    margin-bottom: 32px;
    transition: background-color 0.2s;

    .toolImg {
      width: 24px;
      height: 24px;
      margin-bottom: 10px;
    }

    span {
      font-size: 12px;
      color: #00011b;
    }

    &.active,
    &:hover {
      i {
        color: #165deb;
      }

      span {
        font-weight: bold;
        color: #165deb;
      }
    }
  }
}

.tkBox {
  .el-form-item__label {
    font-size: 14px;
    color: #00011b;
    line-height: 16px;
    margin-bottom: 4px;
    font-weight: normal;
    padding: 0;
  }

  .el-form-item {
    margin-bottom: 24px;
  }

  ::v-deep .el-form-item--medium .el-form-item__label {
    height: 30px;
    line-height: 30px !important;
    font-size: 13px;
    color: rgba(0, 1, 27, 0.5);
  }

  ::v-deep .el-input--medium .el-input__inner {
    height: 52px;
    line-height: 52px !important;
    font-size: 16px;
  }
}

.dropdown-wrapper {
  width: 100%;
}

.moTitle {
  font-size: 12px;
  color: rgba(0, 1, 27, 1);
  padding-left: 17px;
  line-height: 32px;
}

.moText {
  color: var(--color-, rgba(0, 1, 27, 0.5));
  font-family: "PingFang SC";
  font-size: 13px;
  font-weight: 400;
}

.el-dropdown-link {
  color: #333;
  cursor: pointer;
  padding: 7px;
  padding-left: 15px;
  border: 1px solid #c4c6cc;
  border-radius: 4px;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 16px;
}

.el-dropdown-link-icon {
  margin-left: 5px;
}

.close {
  text-align: right;
  font-size: 22px;
  height: 31px;
  position: relative;
  z-index: 2;
  background: #fff;
  i {
    position: absolute;
    right: 19px;
    bottom: -7px;
    cursor: pointer;
  }
}
</style>
